#include "serialpro.h"
#include "ui_serialpro.h"
#include <QMessageBox>
#include <QDataStream>
serialpro::serialpro(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::serialpro)
{
    ui->setupUi(this);

    this->setWindowTitle("串口助手");                //设置窗口标题

    connect(&Serial, &QSerialPort::readyRead , this , &serialpro::Serial_read);

    ui->bandRateBox->setCurrentIndex(0);    //波特率默认9600

}

serialpro::~serialpro()
{
    delete ui;
}
//串口控制 槽函数
void serialpro::on_open_Button_clicked()
{
    if(ui->open_Button->text() == QString("打开串口"))  //串口未打开
    {
        //设置端口号
        Serial.setPortName(ui->comBox->currentText());
        //设置波特率
        Serial.setBaudRate(ui->bandRateBox->currentText().toInt());
        //设置数据位
        switch (ui->dataBitBox->currentText().toInt())
        {
            case 8: Serial.setDataBits(QSerialPort::Data8); break;
            case 7: Serial.setDataBits(QSerialPort::Data7); break;
            case 6: Serial.setDataBits(QSerialPort::Data6); break;
            case 5: Serial.setDataBits(QSerialPort::Data5); break;
            default: break;
        }
        //设置停止位
        switch (ui->stopBitBox->currentText().toInt())
        {
            case 1: Serial.setStopBits(QSerialPort::OneStop);break;
            case 2: Serial.setStopBits(QSerialPort::TwoStop);break;
            default:break;
        }
        //设置校验方式
        switch (ui->checkoutBox->currentIndex())
        {
            case 0: Serial.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置流控制模式
        Serial.setFlowControl(QSerialPort::NoFlowControl);
        //打开串口
        if(Serial.open(QIODevice::ReadWrite)==false)
        {
            QMessageBox::warning(NULL , "提示", "串口打开失败！");
            return;
        }
        // 失能串口设置控件
        ui->comBox->setEnabled(false);
        ui->checkoutBox->setEnabled(false);
        ui->bandRateBox->setEnabled(false);
        ui->dataBitBox->setEnabled(false);
        ui->stopBitBox->setEnabled(false);
        ui->search_Button->setEnabled(false);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("关闭串口"));
    }
    else       //串口已经打开
    {
        Serial.close();
        // 使能串口设置控件
        ui->comBox->setEnabled(true);
        ui->checkoutBox->setEnabled(true);
        ui->bandRateBox->setEnabled(true);
        ui->dataBitBox->setEnabled(true);
        ui->stopBitBox->setEnabled(true);
        ui->search_Button->setEnabled(true);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("打开串口"));
    }
}

void serialpro::on_search_Button_clicked()
{
    // 清除当前显示的端口号
    ui->comBox->clear();
    //检索端口号
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comBox->addItem(info.portName());
    }
}

void serialpro::on_clear_r_Button_clicked()
{
    ui->receiveEdit->clear();
}

void serialpro::on_send_Button_clicked()
{
    if(Serial.isOpen()==false)  //判断串口是否正常打开
    {
        QMessageBox::warning(NULL , "提示", "请打开串口！");
        return;
    }
    //toPlainText() 转换为纯文本格式
    //toUtf8() 转换为UTF-8 编码
    QByteArray senddata = ui->SendEdit->toPlainText().toUtf8();

    //判断是否有非16进制字符
    if(ui->send16Box->isChecked()==true) //勾选了16进制发送
     {

        int cnt = senddata.size();          //要发送数据的长度

        char *data = senddata.data();
        for(int i=0;i<cnt;i++)//判断是否有非16进制字符
        {
            if(data[i]>='0' && (data[i]<='9'))
                continue;
            else if(data[i]>='a' && (data[i]<='f'))
                continue;
            else if(data[i]>='A' && (data[i]<='F'))
                continue;
            else if(data[i] == ' ')     //输入为空格
                continue;
            else
            {
                QMessageBox::warning(NULL , "提示", "输入非16进制字符！");
                return;
            }
        }

        //字符串转化为16进制数   "1234" --> 0X1234
        //转换时会自动除去非16进制字符
        senddata = senddata.fromHex(senddata);
    }
    //勾选了发送新行
    if(ui->newlineBox->isChecked()==true)
    {
        int cnt = senddata.size();
        senddata = senddata.insert(cnt,"\r\n"); //插入回车换行符
    }

    Serial.write(senddata); //通过串口发送数据
}
//显示收到的数据
void serialpro::Serial_read()
{
    //读取串口收到的数据
    QByteArray buffer = Serial.readAll();
    //判断是否需要16进制显示
    if(ui->show16Box->isChecked()==true)
    {
        buffer = buffer.toHex() ;//转换为16进制   例："1234" -->“31323334”
    }
    QString receive = QString(buffer);
    //在接受窗口显示收到的数据
    ui->receiveEdit->insertPlainText(receive);
}
